﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;

namespace Mimoza.RdpPlugin
{
    public class DesktopSyncOld
    {
        const string FilesPluginTag = "mimozafiletag:";

        public static void Replace(string filePath)
        {
            Replace(filePath, Common.GlobalSettings.DesktopPath);
        }

        public static void Replace(string filePath, string folderPath)
        {
            string fileTo = GetFileName(filePath, folderPath);
            string policyIdFrom = GetFilePolicyId(filePath);

            if (string.IsNullOrEmpty(policyIdFrom)) return;

            ReplaceFile(filePath, fileTo, policyIdFrom, folderPath);
        }

        public static void Remove(string filePath)
        {
            Remove(filePath, Common.GlobalSettings.DesktopPath);
        }

        public static void Remove(string filePath, string folderPath)
        {
            string policyIdFrom = Path.GetExtension(filePath).Substring(1);

            foreach (string fileName in Directory.GetFiles(folderPath, "*.rdp"))
            {
                string policyIdTo = GetFilePolicyId(fileName);
                if (!string.IsNullOrEmpty(policyIdTo) && policyIdTo == policyIdFrom)
                {
                    File.Delete(fileName);
                }
            }
        }

        public static void Do(string filesFolder)
        {
            Do(filesFolder, Common.GlobalSettings.DesktopPath, false);
        }

        public static void Do(string filesFolder, string folderPath, bool bOnlyStartupFilde)
        {
            Directory.CreateDirectory(filesFolder);

            List<string> filesPolicyIds = new List<string>();
            foreach (string fileName in Directory.GetFiles(filesFolder, "*.*"))
            {
                bool bIsStrartup;
                string policyIdFrom = GetFilePolicyId(fileName, out bIsStrartup);
                if (string.IsNullOrEmpty(policyIdFrom)) continue;
                if (bOnlyStartupFilde && !bIsStrartup) continue;

                Replace(fileName, folderPath);
                filesPolicyIds.Add(Path.GetExtension(fileName).Substring(1));
            }

            EraseNotExistsPluginFiles(filesPolicyIds, folderPath);
        }

        private static string GetFileName(string filePath, string folderPath)
        {
            string fileName = Path.GetFileNameWithoutExtension(filePath) + ".rdp";

            return Path.Combine(folderPath, fileName);
        }

        private static void ReplaceFile(string filePath, string fileTo, string policyIdFrom,
            string folderPath)
        {
            bool bFileReplace = true;
            int nameSuffixCount = 1;
            do
            {
                bFileReplace = true;
                fileTo = MakeCountedName(fileTo, nameSuffixCount);
                if (File.Exists(fileTo))
                {
                    string policyIdTo = GetFilePolicyId(fileTo);
                    if (!string.IsNullOrEmpty(policyIdTo) && policyIdTo != policyIdFrom)
                    {
                        bFileReplace = false;
                        nameSuffixCount++;
                    }
                }

                if (bFileReplace)
                {
                    File.Copy(filePath, fileTo, true);
                    ErasePolicyFile(fileTo, policyIdFrom, folderPath);
                }
            }
            while (!bFileReplace);
        }

        private static void EraseNotExistsPluginFiles(List<string> filesPolicyIds, string folderPath)
        {
            try
            {
                foreach (string fileName in Directory.GetFiles(folderPath, "*.rdp"))
                {
                    string policyIdTo = GetFilePolicyId(fileName);
                    if (string.IsNullOrEmpty(policyIdTo)) continue;

                    int index = filesPolicyIds.FindIndex(polId => polId == policyIdTo);
                    if (index<0)
                    {
                        File.Delete(fileName);
                    }
                }
            }
            catch (System.Exception e)
            {
                Common.Logger.Log.Info("Mimoza.DesktopSyncOld: error in erase desktop file. Errro - '" +
                    e.ToString() + "'.");
            }
        }

        private static void ErasePolicyFile(string exceptFileTo, string policyIdFrom, string folderPath)
        {
            try
            {
                foreach (string fileName in Directory.GetFiles(folderPath, "*.rdp"))
                {
                    if (exceptFileTo == fileName) continue;

                    string policyIdTo = GetFilePolicyId(fileName);
                    if (string.IsNullOrEmpty(policyIdTo)) continue;

                    if (policyIdTo==policyIdFrom)
                    {
                        File.Delete(fileName);
                    }
                }
            }
            catch (System.Exception e)
            {
                Common.Logger.Log.Info("Mimoza.DesktopSyncOld: erron in erase policy desktop file. Errro - '" +
                    e.ToString() + "'.");
            }
        }

        private static bool IsPluginFile(string filePath)
        {
            using (TextReader reader = new StreamReader(filePath))
            {
                string text = reader.ReadToEnd();
                return text.Contains(FilesPluginTag) ? true : false;
            }
        }

        private static string GetFilePolicyId(string filePath)
        {
            bool bIsStartup;
            return GetFilePolicyId(filePath, out bIsStartup);
        }

        private static string GetFilePolicyId(string filePath, out bool bIsStartup)
        {
            const string c_FileTag = FilesPluginTag;
            const string c_FileStartupTag = "mimozaisstartup:";
            const int c_PolicyIdLen = 36;

            string policyId = "";
            bIsStartup = false;

            try
            {
                using (TextReader reader = new StreamReader(filePath))
                {
                    string fileText = reader.ReadToEnd();
                    int pos = fileText.IndexOf(c_FileTag);
                    if (pos >= 0)
                    {
                        policyId = fileText.Substring(pos + c_FileTag.Length, c_PolicyIdLen);
                    }
                    pos = fileText.IndexOf(c_FileStartupTag);
                    if (pos >= 0)
                    {
                        bIsStartup = (0!=int.Parse(fileText.Substring(pos + c_FileStartupTag.Length, 1)));
                    }
                }
            }
            catch (System.Exception)
            {
            }

            return policyId;
        }

        private static string MakeCountedName(string fileName, int count)
        {
            if (count <= 1) return fileName;

            string fileNameWithExtent = Path.Combine(Path.GetDirectoryName(fileName),
                Path.GetFileNameWithoutExtension(fileName));

            fileName = fileNameWithExtent + "(" + count.ToString() + ")" +
                Path.GetExtension(fileName);

            return fileName;
        }

    }
}
